package com.kjj.gift.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.kjj.gift.clients.LoginUserClient;
import com.kjj.gift.domain.Employee;
import com.kjj.gift.domain.LoginUser;
import com.kjj.gift.domain.Tenant;
import com.kjj.gift.dto.LoginUserMealDto;
import com.kjj.gift.dto.TenantEnterDto;
import com.kjj.gift.exception.BusinessException;
import com.kjj.gift.exception.asserts.Assert;
import com.kjj.gift.exception.code.StatusCode;
import com.kjj.gift.mapper.EmployeeMapper;
import com.kjj.gift.mapper.TenantMapper;
import com.kjj.gift.query.TenantQuery;
import com.kjj.gift.service.ITenantService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.kjj.gift.util.AjaxResult;
import com.kjj.gift.util.PageList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kjj
 * @since 2022-10-09
 */
@Service
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {

    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private LoginUserClient loginUserClient;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Override
    public PageList<Tenant> selectPageList(TenantQuery query) {
        Page<Tenant> page = new Page<>(query.getPage(), query.getRows());
        List<Tenant> rows = tenantMapper.selectPageList(page, query);
        return new PageList<>(page.getTotal(),rows);
    }

    @Override
    @Transactional
    public AjaxResult settlement(TenantEnterDto tenantEnterDto) {

        //1参数校验 完成
        //1.1 null校验
        //1.2 店铺是否存在校验
        //1.3 店铺管理员校验
        validate(tenantEnterDto);

        //2 保存数据  店铺 店铺管理员 登陆信息  用户套餐中间表
        //2.1 保存登陆信息及用户套餐中间表并发返回loginId-->其他服务的功能（openfegin） loginUser+mealId=Map/Dto
        //方案1：谁提供服务谁写 好处：能直接用它的公共代码,坏处就是要让别人写接口---一个团队甚至一个人
        //方案2：更加接口文档自己来写  好处：没有任何耦合，坏处：有重复dto----如果两个团队分别写服务
        /**
         * 开发思路：
         * 存储dto，包括店铺信息，管理员信息，套餐id，保存到中间表
         * 先存登录信息： loginuser表，根据type分辨管理员还是用户，可以获得login_id用于存管理员信息的login_id
         * 中间表：
         *     获取meal_id,tenant_id,状态默认0
         *     套餐和租户一起保存，存id
         * 管理员：
         *     存的时候先设置下login_id,然后保存
         * 店铺信息：
         *     存tenant，获取管理员id设置进去
         */
        String username = tenantEnterDto.getAdmin().getUsername();
        String password = tenantEnterDto.getAdmin().getPassword();
        String tel = tenantEnterDto.getAdmin().getTel();
        String email = tenantEnterDto.getAdmin().getEmail();
        Long mealId = tenantEnterDto.getMealId();
        LoginUserMealDto loginUserMealDto = new LoginUserMealDto();
        LoginUser loginUser = new LoginUser();
        loginUser.setUsername(username);
        loginUser.setPassword(password);
        loginUser.setTel(tel);
        loginUser.setEmail(email);
        loginUser.setType(1);
        loginUserMealDto.setLoginUser(loginUser);
        loginUserMealDto.setMealId(mealId);  //自己设置类型 默认为0 因为保存的是管理员的信息
        AjaxResult ajaxResult = loginUserClient.addLoginUserMeal(loginUserMealDto);
        if (!ajaxResult.isSuccess()){
            //抛出异常
            throw new RuntimeException("远程调用错误！请重试");
        }
        try {
            Long loginUserId = Long.valueOf(ajaxResult.getResultObj().toString());
            //2.2  店铺管理员
            Employee admin = new Employee();
            admin.setUsername(username);
            admin.setPassword(password);
            admin.setEmail(email);
            admin.setTel(tel);
            admin.setLoginId(loginUserId);
            admin.setState(0);
            admin.setType(1);
            employeeMapper.insert(admin);
            System.out.println("管理员id："+admin.getId());
            //2.3 店铺信息
            Tenant tenant = tenantEnterDto.getTenant();
            tenant.setState(0);
            tenant.setAdminId(admin.getId());
            tenantMapper.insert(tenant);
            admin.setTenantId(tenant.getId());
            EntityWrapper<Employee> wrapper = new EntityWrapper<>();
            wrapper.eq("id", admin.getId());
            employeeMapper.update(admin,wrapper);
            HashMap<String,Object> map = new HashMap();
            map.put("meal_id", mealId);
            map.put("tenant_id", tenant.getId());
            tenantMapper.addmealAndtenant(map);
            return AjaxResult.me().setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setMessage(e.getMessage()+" 系统错误！");
        }
    }
    private void validate(TenantEnterDto tenantEnterDto) {

/*        //1.1 null检验   抛出异常类
        if (tenantEnterDto==null)
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        if (StringUtils.isEmpty(tenantEnterDto.getAdmin()) || StringUtils.isEmpty(tenantEnterDto.getMealId()) ||
                StringUtils.isEmpty(tenantEnterDto.getTenant()) )
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        if (tenantEnterDto.getAdmin().getUsername()==null ||tenantEnterDto.getTenant().getCompanyName()==null)
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        if (StringUtils.isEmpty(tenantEnterDto.getAdmin().getUsername())||
                StringUtils.isEmpty(tenantEnterDto.getAdmin().getPassword())|| StringUtils.isEmpty(tenantEnterDto.getAdmin().getComfirmPassword()))
        {
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        }
        //1.2 两次密码比对
        if (!tenantEnterDto.getAdmin().getPassword().trim().equals(tenantEnterDto.getAdmin().getComfirmPassword().trim()))
            throw new BusinessException("两次密码不一致");

        //1.3 店铺是否存在
        Tenant tenantByDb = tenantMapper.loadByName(tenantEnterDto.getTenant().getCompanyName());
        if (tenantByDb!=null)
            throw new BusinessException("该店铺已经存在！");*/
        //===================================== 方案二
       /* //1参数校验
        //1.1 null校验
        Employee admin = tenantEnterDto.getAdmin();
        Tenant tenant = tenantEnterDto.getTenant();
        Long mealId = tenantEnterDto.getMealId();
        //用户信息校验
        Assert.assertNotNull(admin,"系统错误！请输入相关信息后再操作");
        Assert.assertNotEmpty(admin.getUsername(),"系统错误！请输入管理员名后再操作");
        Assert.assertNotEmpty(admin.getTel(), "系统错误！请输入管理员电话后再操作");
        Assert.assertNotEmpty(admin.getPassword(),"系统错误！请输入密码后再操作");
        Assert.assertNotEmpty(admin.getComfirmPassword(),"系统错误！请输入确认密码后再操作");

        //两次密码比对
        Assert.assertEquals(admin.getPassword(),admin.getComfirmPassword(),"两次密码不一致");
        //租户信息校验
        Assert.assertNotNull(tenant,"系统错误！请输入租户信息后再操作");
        Assert.assertNotEmpty(tenant.getAddress(),"系统错误！请输入租户地址后再操作");
        Assert.assertNotEmpty(tenant.getCompanyName(),"系统错误！请输入租户名称后再操作");
        //套餐校验
        Assert.assertNotNull(mealId,"系统错误！请输入相关信息后再操作");
        //1.2 店铺是否存在校验
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>().eq("company_name", tenant.getCompanyName()));
        Assert.assertListIsEmpty(tenants,"该店铺已经存在！");
        //1.3 管理员存在校验
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("username",admin.getUsername()));
        Assert.assertListIsEmpty(employees,"请登录，在后台添加租户提交审核！");*/
        //1参数校验
        //1.1 null校验
        Employee admin = tenantEnterDto.getAdmin();
        Tenant tenant = tenantEnterDto.getTenant();
        //两次密码比对
        Assert.assertEquals(admin.getPassword(),admin.getComfirmPassword(),"两次密码不一致");
        //1.2 店铺是否存在校验
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>().eq("company_name", tenant.getCompanyName()));
        Assert.assertListIsEmpty(tenants, StatusCode.CODE_400_TENANT_EXSIT);
        //1.3 管理员存在校验
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("username",admin.getUsername()));
        Assert.assertListIsEmpty(employees, StatusCode.CODE_400_TENANT_ADMIN_EXSIT);
    }
}
